using System;
using System.Collections.Generic;
using System.Web.Mvc;
using FamilyTreeProject.Common;
using System.Net;
using FamilyTreeProject.Web.Components;

namespace FamilyTreeProject.Web.Controllers
{
    public class IndividualsController : Controller
    {
        #region Private Members

        private const int DEFAULT_PAGE_SIZE = 20;
        private const int DEFAULT_TREE_ID = 1;
        private IIndividualsService individuals;

        #endregion

        #region Constructors

        /// <summary>
        /// Constructs an IndividualsController
        /// </summary>
        /// <param name="individuals">An IIndividualsService</param>
        public IndividualsController(IIndividualsService individuals)
        {
            if (individuals == null) throw new ArgumentNullException("individuals");
            this.individuals = individuals;
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Saves an Individual
        /// </summary>
        /// <param name="individual">The individual to save</param>
        /// <param name="form">The form data</param>
        /// <param name="redirectToView">The View to redirect to if successful</param>
        /// <param name="successMessage">The success message to display</param>
        /// <param name="redirectToViewOnError">The View to redirect to if an error</param>
        /// <returns></returns>
        private ActionResult Save(Individual individual, string redirectToView, string successMessage, string redirectToViewOnError)
        {
            try
            {
                UpdateModel(individual, new[] {"FirstName", "LastName"});
                individual.TreeId = DEFAULT_TREE_ID;

                if (individual.Id > 0)
                    individuals.UpdateIndividual(individual);
                else
                    individuals.AddIndividual(individual);

                TempData[Constants.KEY_Message] = successMessage;

                return RedirectToAction(redirectToView, new { id = individual.Id });
            }
            catch (Exception exc)
            {
                TempData[Constants.KEY_Message] = Constants.MESSAGE_Error;

                return RedirectToAction(redirectToViewOnError, individual);
            }
        }
 
	    #endregion        
        
        #region Public Methods

        [ActionName(Constants.ACTION_Delete)]
        public ActionResult Delete(int id)
        {
            Individual ind = individuals.GetIndividual(id, false);
            if (ind == null)
            {
                return View(Constants.VIEW_Error).With(Constants.KEY_Message, Constants.MESSAGE_Individual_NotFound)
                                                 .WithStatusCode(HttpStatusCode.NotFound);
            }

            try
            {
                individuals.DeleteIndividual(ind);

                return RedirectToAction(Constants.ACTION_List);
            }
            catch (Exception)
            {
                TempData[Constants.KEY_Message] = Constants.MESSAGE_Error;

                return RedirectToAction(Constants.VIEW_View, ind);
            }

        }

        [AcceptVerbs("GET"), ActionName(Constants.ACTION_Edit)]
        public ActionResult Edit(int id)
        {
            Individual ind = individuals.GetIndividual(id, false);
            if (ind == null)
            {
                return View(Constants.VIEW_Error).With(Constants.KEY_Message, Constants.MESSAGE_Individual_NotFound)
                                                    .WithStatusCode(HttpStatusCode.NotFound);
            }
            else
                return View(Constants.VIEW_Edit).With(ind);
        }

        [AcceptVerbs("POST"), ActionName(Constants.ACTION_Edit)]
        public ActionResult Edit(int id, FormCollection form)
        {
            return Save(individuals.GetIndividual(id, false), Constants.VIEW_Edit, Constants.MESSAGE_Individual_Updated, Constants.VIEW_Edit);
        }

        [ActionName(Constants.ACTION_Index)]
        public ActionResult Index()
        {
            return List(null);
        }

        [ActionName(Constants.ACTION_List)]
        public ActionResult List(int? id)
        {
            IList<Individual> results = individuals.GetIndividuals(DEFAULT_TREE_ID, id ?? 0, DEFAULT_PAGE_SIZE);

            if (results.Count == 0)
                return View(Constants.VIEW_Error).With(Constants.KEY_Message, Constants.MESSAGE_Page_NotFound)
                                                    .WithStatusCode(HttpStatusCode.NotFound);
            else
                return View(Constants.VIEW_List).With(results);
        }

        [AcceptVerbs("GET"), ActionName(Constants.ACTION_New)]
        public ActionResult New()
        {
            return View(Constants.VIEW_New).With(new Individual());
        }

        [AcceptVerbs("POST"), ActionName(Constants.VIEW_New)]
        public ActionResult New(FormCollection form)
        {
            return Save(new Individual(), Constants.VIEW_View, Constants.MESSAGE_Individual_Created, Constants.VIEW_New);
        }

        [ActionName(Constants.ACTION_View)]
        public ActionResult ViewAction(int id)
        {
            Individual ind = individuals.GetIndividual(id, true);
            if (ind == null)
            {
                return View(Constants.VIEW_Error).With(Constants.KEY_Message, Constants.MESSAGE_Individual_NotFound)
                                                    .WithStatusCode(HttpStatusCode.NotFound);
            }
            else
                return View(Constants.VIEW_View).With(ind);
        }

        #endregion
    }
}
